﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Gumini.JulaDB.Enums;
using Gumini.JulaDB.Provider;

namespace Gumini.JulaDB.Expressions.Functions
{
    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    internal static class FunctionFactory
    {
        private static readonly Dictionary<Tuple<string, int>, Function> _functions = new Dictionary<Tuple<string, int>, Function>();

        static FunctionFactory()
        {
            var functionTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(Function)) && !t.IsAbstract);
            foreach(var type in functionTypes)
                RegisterFunction((Function)Activator.CreateInstance(type));
        }

        private static void RegisterFunction(Function function)
        {
            _functions.Add(Tuple.Create(function.Name, function.NumberOfArguments), function);
        }

        public static Function GetFunction(string name, int numberOfArguments)
        {
            var id = Tuple.Create(name.ToLowerInvariant(), numberOfArguments);
            if (!_functions.ContainsKey(id))
                throw new JulaDbException(ErrorCode.UnsupportedFunction, "Function {0}/{1} is not supported.", name, numberOfArguments);
            return _functions[id];
        }
    }
}
